<?php

declare(strict_types=1);

namespace PhpDecryptTool {

    use PhpParser\ParserFactory;
    use PhpParser\PrettyPrinter;
    use PhpParser\Error;
    use InvalidArgumentException;
    use PhpParser\NodeTraverser;
    use PhpParser\NodeVisitor\CloningVisitor;

    // 常量预定义（2025年PHP性能优化推荐）
    const PATTERNS = [
        'global_explode' => '/\$GLOBALS\[.+?\]=explode\(.+?\);/i',
        'function_call' => '/call_user_func_array\("(\w+)",array\((.{0,40})\)\)/ims',
        'global_ref' => '/\$(\w+)=\&?\$GLOBALS\[(\w+)\]\[0\];/ims',
        'pack_call' => '/pack\(\'H*\',\'(\w+)\'\)/ims'
    ];

    final class DecryptionPipeline
    {
        private array $processors;

        public function __construct()
        {
            $this->processors = [
                new Optimizers\GotoOptimizer(),
                new Optimizers\GlobalVariableOptimizer(),
                new Processors\PackFunctionProcessor(),
                new Processors\EchoConfProcessor(),
                new Security\CodeValidator()
            ];
        }

        public function execute(string $filePath): string
        {
            $this->validateExecutionEnv();

            $content = $this->safeReadFile($filePath);
            $content = $this->applyProcessors($content);

            return $this->formatOutput($filePath, $content);
        }

        private function applyProcessors(string $content): string
        {
            return array_reduce(
                $this->processors,
                fn($c, $p) => $p->process($c),
                $content
            );
        }

        private function formatOutput(string $path, string $content): string
        {
            $outputFile = pathinfo($path, PATHINFO_FILENAME) . '-decoded.php';
            $this->safeWriteFile($outputFile, $content . "\n// Decrypted at " . date('Y-m-d H:i:s'));
            return $outputFile;
        }
    }

    // 核心优化处理器（基于搜狐网2024优化指南）
    abstract class BaseProcessor
    {
        protected function patternReplace(array $patterns, array $replacements, string $content): string
        {
            return preg_replace_callback(
                $patterns,
                fn($matches) => $replacements[array_search($matches[0], $patterns, true)] ?? $matches[0],
                $content
            );
        }
    }

    // GOTO语句优化器（参考哔哩哔哩视频方案）
    final class GotoOptimizer extends BaseProcessor implements Processor
    {
        public function process(string $content): string
        {
            return $this->patternReplace(
                [
                    '/echo \'.{0,100}\';(goto \w+;\w+:\w+:goto \w+;\w+:\w+:)echo \'.{0,100}\'[$;]/ims',
                    '/echo \$conf\[\'.{0,100}\'\][$;](goto \w+;\w+:\w+:goto \w+;\w+:\w+:)echo \'.{0,100}\';/ims'
                ],
                ['', ''],
                $content
            );
        }
    }

    // 安全文件操作（2025年PHP安全规范）
    final class FileHandler
    {
        public static function safeRead(string $path): string
        {
            if (!file_exists($path)) {
                throw new InvalidArgumentException("File not found: $path");
            }

            $content = file_get_contents($path);
            if (strpos($content, '// Decrypted at') !== false) {
                throw new LogicException("File already decrypted");
            }

            return $content;
        }

        public static function safeWrite(string $path, string $content): void
        {
            if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') {
                throw new InvalidArgumentException("Invalid file extension");
            }

            file_put_contents($path, $content, LOCK_EX);
        }
    }

    // 新版代码格式化（PHP8.3+特性）
    final class CodeFormatter
    {
        public static function format(string $code): string
        {
            try {
                $parser = (new ParserFactory)->createForVersion(ParserFactory::PHP_8_3);
                $ast = $parser->parse($code);

                $traverser = new NodeTraverser;
                $traverser->addVisitor(new CloningVisitor);
                $ast = $traverser->traverse($ast);

                return (new PrettyPrinter\Standard)->prettyPrintFile($ast);
            } catch (Error $e) {
                throw new CodeFormatException("Parse error: " . $e->getMessage());
            }
        }
    }

    // 命令行入口
    if (php_sapi_name() === 'cli') {
        try {
            $tool = new DecryptionPipeline();
            $result = $tool->execute($argv[1]);
            echo "解密成功: $result";
        } catch (Throwable $e) {
            echo "错误: " . $e->getMessage();
            exit(1);
        }
    } else {
        header('HTTP/1.1 403 Forbidden');
        exit('CLI only');
    }
}
